package com.zsd.android.webrtcdemo.exceptions;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExceptionHandler implements Thread.UncaughtExceptionHandler {

    private static volatile ExceptionHandler instance;
    private final Thread.UncaughtExceptionHandler mDefaultHandler;
    private final ExecutorService executorService;
    private Context mContext;
    private Handler mHandler;

    private ExceptionHandler() {
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        executorService = Executors.newCachedThreadPool();
    }

    public static ExceptionHandler getInstance() {
        ExceptionHandler handler = instance;
        if (handler == null) {
            synchronized (ExceptionHandler.class) {
                if (handler == null) {
                    handler = new ExceptionHandler();
                    instance = handler;
                }
            }
        }
        return handler;
    }

    public void init(Context mContext) {
        this.mContext = mContext;
        Thread.setDefaultUncaughtExceptionHandler(this);
        mHandler = new Handler(Looper.getMainLooper());
        executorService.execute(() -> {
            mHandler.post(() -> {
                //主线程异常拦截
                while (true) {
                    try {
                        Looper.loop();//主线程的异常会从这里抛出
                    } catch (Throwable e) {
                        Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                }
                });
        });
    }

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        boolean b = handleException(e);
        if (!b && mDefaultHandler != null) {
            //没有处理异常则交给系统处理
            mDefaultHandler.uncaughtException(t, e);
        }
    }

    private boolean handleException(Throwable throwable) {
        if (throwable == null) {
            return false;
        }
        return true;
    }
}
